# --------------------------------------------------------------------------------
#  NoiseTube Web application
#  
#  Copyright (C) 2008-2010 SONY Computer Science Laboratory Paris
#  Portions contributed by Vrije Universiteit Brussel (BrusSense team), 2008-2011
# --------------------------------------------------------------------------------
#  This library is free software; you can redistribute it and/or modify it under
#  the terms of the GNU Lesser General Public License, version 2.1, as published
#  by the Free Software Foundation.
#  
#  This library is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
#  details.
#  
#  You should have received a copy of the GNU Lesser General Public License along
#  with this library; if not, write to:
#    Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor,
#    Boston, MA  02110-1301, USA.
#  
#  Full GNU LGPL v2.1 text: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
#  NoiseTube project source code repository: http://code.google.com/p/noisetube
# --------------------------------------------------------------------------------
#  More information:
#   - NoiseTube project website: http://www.noisetube.net
#   - Sony Computer Science Laboratory Paris: http://csl.sony.fr
#   - VUB BrusSense team: http://www.brussense.be
# --------------------------------------------------------------------------------
 
class Cartasur::UsersController < Cartasur::ApplicationController
  #include Geokit::Geocoders

  before_filter :login_redirect, :only  => [:show]

  def index

    location=get_location_by_ip
    if (!location.nil? && (location[:country_code2]=='FR') && (params[:locale].nil?))
      I18n.locale='fr'
    end
    @location="#{location[:city_name]}, #{location[:country_code2]}" unless location.nil?
    #render :layout => "layouts/cartasurapplication"

    #filter types of users
    if params[:l].nil?
        @cusers = Cartasur::User.where("login like 'cartasur%'").paginate(:per_page => 10, :order=>"id", :page => params[:page])
    else
        @cusers = Cartasur::User.where("role like '%#{params[:l]}%'" ).paginate(:per_page => 10, :order=>"id", :page => params[:page])
    end
end
  def new
    @user = Cartasur::User.new
    unless params[:objective_id].nil?
      @objective= Cartasur::Objective.find(params[:objective_id])
      @user.objectives.build(:objective_id => @objective.id)
    end
  end

  def edit
    #get the users objectives

    @user = Cartasur::User.find(params[:id])

    @user = (current_user unless current_user.nil? )  if @user.nil?

    city = City.find_by_id(@user.city_id)
    @user[:location] = "#{city.name}, #{city.country}"
    @user

    #questionnaire answers
    @qn_questions = Cartasur::Question.get_questions(Cartasur::Question::QUESTION_TYPES[:questionnaire])

    @qn_answers = @user.questionnaire_answers

    x = 3
  end

  def create
    user_hash = params[:cartasur_user]
    unless user_hash.nil? and current_user.role != "admin"

         @user = Cartasur::User.new


         @user.password = user_hash[:password]
         @user.login = user_hash[:login]
         @user.password = user_hash[:password]
         @user.password_confirmation = user_hash[:password_confirmation]
         @user.email = user_hash[:email]
         #email2
         @user.email2 = @user.email

         @user.location = user_hash[:location]
         @user.phonemodel = user_hash[:phonemodel]

         @user.role = user_hash[:role]

         s = Geocoder.search(user_hash[:location])

         if s.blank? || s[0].city.nil?
           @user.errors.add(:location, "The home town you specified was not found")
         else

           city=City.build_city(s)
           @user.city=city

         end
    end

     if @user.save
       flash[:notice] = "Created the user sucessfully"
       redirect_to "/cartasur/users" , :notice =>"The user was successfully saved!"
     else
       flash[:alert] = "Could not create the user. Please try again."
       render 'new'
     end
  end



  def show
    @user  = Cartasur::User.find(params[:id])

    respond_to do |format|

      # only public track
      clause="public=true" unless @user==current_user

      format.html {
        @summary={}
        @summary[:last_activity]=@user.measures.find(:last).made_at unless @user.measures.find(:last).nil?
        @summary[:measures_size]=@user.measures_size
        @summary[:tags_assignement_size]= @user.tags_size #@user.owned_taggings.count
        @tags=@user.prominent_tags.all

        @tracks=Cartasur::Track.where("user_id = #{@user.id}").paginate(:conditions=>clause, :per_page => 10, :order=>"tracks.created_at desc", :page => params[:page])
        x = 1
        # #@onload="initialize();" #@onunload="GUnload();"
      }

      format.rss{
        @tracks=@user.tracks.all(:conditions=>clause, :order=>"tracks.created_at desc", :limit=>10)
        render :layout=>false,:mimetype =>:rss
      }

      format.js {
        render :update do |page|
          p params
          @tracks=@user.tracks.paginate(:all,:conditions=>clause, :per_page => 10, :order=>"tracks.created_at desc", :page => params[:page])
          page.replace_html 'results', :partial => 'track_list'
        end
      }
      format.jpg{
        u = Cartasur::User.find(params[:id])
        if FileTest.exists?("#{Rails.root}#{u.image_url.thumb.to_s}")
          redirect_to u.image_url.thumb.to_s, mimetype: :jpg
        else
          redirect_to '/images/default_user.gif'
        end
      }
    end

  end

  def update

    @user = Cartasur::User.find(params[:id])


    location = params[:cartasur_user][:location]
    user_hash = params[:cartasur_user].except(:location)

    s = Geocoder.search(location)

    if s.blank? || s[0].city.nil?
      @user.errors.add(:location, "The location you specified was not found")
    else

      city=City.build_city(s)
      @user.city=city
    end

    if @user.update_attributes(user_hash)
      flash[:notice] = "The user was successfully updated!"
      redirect_to :controller => 'cartasur/users', :action => 'edit'
    else
      flash[:alert] = "There was a problem when updating"
    end
  end

  def showobjectives
    @cuser  = Cartasur::User.find(params[:id])
    #@cobjectives = @cuser.user_protocols.paginate(:per_page => 15, :order=>"id", :page => params[:page]) unless @cuser.nil?
    case
      when params[:l] == "yes"
        @results = @cuser.completed_protocols unless @cuser.nil?
      when params[:l] == "no"
        @results = @cuser.incomplete_protocols unless @cuser.nil?
      else
        @results = @cuser.all_protocols_plus_info unless @cuser.nil?

    end
  end

  # -------- user authentication -------------
  def authenticate_user
    redirect_to "/cartasur/login" unless logged_in? && @user==current_user
  end

  def login_redirect
    unless logged_in?
      session[:return_to] = request.fullpath
      redirect_to "/cartasur/login" , notice: "Login first to view the page"
    end
  end

  # ------ uploads -------
  def uploaddata
    @user = Cartasur::User.find(params[:id])
  end

  def uploadxml
    @user = Cartasur::User.find(params[:id])
    # get the uploaded file and read it...
    uploaded_file = params[:xml_file]
    xml_data = uploaded_file.read if uploaded_file.respond_to? :read

    # do we have data from the file?
    unless request.post? and xml_data
      redirect_to root_url
      return
    end

    # append session closing tag if needed:
    closing_tag = "</NoiseTube-Mobile-Session>"
    xml_data += closing_tag if xml_data.rindex(closing_tag).nil?

    begin

      # do we have data from the file?
      if request.get? or xml_data.nil?

        logger.warn("Cartasur: Could not upload the file for "+ @user.try(:login) + " - probably no data or not a post request.")
        flash[:upload_notice] = (t 'cartasur.uploads.uploadfailed')
      else

        # append session closing tag if needed:
        closing_tag = "</NoiseTube-Mobile-Session>"
        xml_data += closing_tag if xml_data.rindex(closing_tag).nil?
        begin
          # parse the data using REXML...
          xml_doc = REXML::Document.new(xml_data)

          #new - 28/05/2013: constraints followed?

          surveyroot = REXML::XPath.first( xml_doc, "//survey")
          # public static final int FOLLOWING_CONSTRAINTS_NO    = 0;
          #public static final int FOLLOWING_CONSTRAINTS_YES   = 1;
          #public static final int FOLLOWING_CONSTRAINTS_MAYBE = 2;
          constraints_followed  = surveyroot.attribute("constraints_followed").try(:value)

          #constraints not followed
          if  constraints_followed.nil? or constraints_followed == "0"
            #directory where to make the move to
            tmp = uploaded_file.tempfile
            file = File.join("public", "uploads", "cartasur", "unprocessed", uploaded_file.original_filename << "-"<< Time.now.to_s(:number))
            #copy to directory
            FileUtils.cp tmp.path, file

            #remove upload, if possible
            #FileUtils.rm tmp
            #ps: i dont create a visited or a track for constraints_followed=0

            flash[:upload_notice] = (t 'cartasur.users.upload.queuedforanalysis')
            redirect_to(@user)
          else
            #constraints followed but no GPS

            #28/05/2013 - Kennedy - Get the objective gps for missing gps values
            svroot = REXML::XPath.first( xml_doc, "//survey")
            protocol_id = svroot.attribute("protocol_id").try(:value)
            protocol = Cartasur::Protocol.find(protocol_id)

            #check if that protocol exists in visiteds table (has been uploaded already)
            already_uploaded = Cartasur::Visited.where({:protocol_id => protocol.id, :user_id => protocol.user.id}).first

            if already_uploaded.nil?


              #save track first
              track=Cartasur::Track.from_xml(xml_doc, protocol.user, protocol, constraints_followed)

              # log successful
              logger.info "Cartasur: Uploading measurements from xml file uploaded by #{@user.login}..... "
              logger.info "Cartasur: A track id #{track.id} with a total of #{track.measures.size} measures was added at #{Time.now}"

              #save surveys
              Cartasur::Answer.savefromxml(xml_doc)

              #save uploaded xml file - for logging purposes
              tmp = uploaded_file.tempfile
              file = File.join("public", "uploads", "cartasur","processed", uploaded_file.original_filename << "-"<< Time.now.to_s(:number))
              #copy to directory
              FileUtils.cp tmp.path, file

              #create a visited
              @visited = Cartasur::Visited.new({protocol_id: protocol_id, track_id: track.id, user_id: protocol.user.id, objective_id: protocol.objective.id})
              if @visited.save
                #done...
                logger.info "Cartasur: Successfully uploaded measurements by #{@user.try(:login)}"

                flash[:upload_notice] = (t 'cartasur.users.upload.successful')
                redirect_to(@user)

              else
                raise "Could not save the visited info for upload by user #{@user.id}"
              end


            else
              #alredy uploaded - copy to duplicates folder

              tmp = uploaded_file.tempfile

              file = File.join("public", "uploads", "cartasur", "duplicates", uploaded_file.original_filename << "-"<< Time.now.to_s(:number))
              dir = File.dirname(file)
              FileUtils.mkdir_p(dir) unless File.directory?(dir)    #create dir

              #copy to directory
              FileUtils.cp tmp.path, file

              flash[:upload_notice] = (t 'cartasur.users.upload.successful')
              redirect_to(@user)
            end

          end
        rescue Exception => exc
          logger.error("Cartasur: Error processing uploaded (XML file): #{exc.message}")
          flash[:error] = "Upload failed, please try again later. (#{exc.message})"
          render :action => 'uploaddata'
        end
      end
    end
  end

  # status of protocols
  def userprotocols

  end
end
